<!-- <template>
  <div class="data-panel">
    <div class="data-item" title="下载XML格式数据" @mousedown="downloadXml()">
      <div class="data-item-icon bpmn-xml"></div>
    </div>
    <div class="data-item" title="下载图片格式数据" @mousedown="downloadImage()">
      <div class="data-item-icon bpmn-img"></div>
    </div>
    <div class="data-item">
      <input type="file" className="data-upload" title="上传XML格式数据" @change="uploadXml($event)" />
      <div class="data-item-icon bpmn-upload"></div>
    </div>
    <div class="data-item" title="下载JSON格式数据" @mousedown="getGraphRawData()">
      <div class="data-item-icon bpmn-look"></div>
    </div>
  </div>
</template> -->
<template>
  <span></span>
</template>
<script lang="ts" setup>
import LogicFlow from '@logicflow/core'
import { lfJson2Xml } from '@logicflow/extension'
import { isArray, intersection, intersectionBy } from 'lodash-es'

function download(filename: string, text: string) {
  const element = document.createElement('a')
  element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text))
  element.setAttribute('download', filename)
  element.style.display = 'none'
  document.body.appendChild(element)
  element.click()
  document.body.removeChild(element)
}

type FileEventTarget = EventTarget & { files: FileList }

const props = defineProps<{
  lf: LogicFlow
}>()

const sortInOut = (data, userTaskData, nodeType) => {
  // logicflow的bug，后续版本应该会修复
  // 后端要求：outgoing一定要在incoming的后面
  if (userTaskData?.constructor === Object) {
    const temp = {}
    for (const key in userTaskData) {
      if (key !== 'bpmn:outgoing' && key !== 'multiInstanceLoopCharacteristics') {
        temp[key] = userTaskData[key]
      }
    }
    for (const key in userTaskData) {
      if (key === 'bpmn:outgoing') {
        temp[key] = userTaskData[key]
      }
    }
    for (const key in userTaskData) {
      if (key === 'multiInstanceLoopCharacteristics') {
        temp[key] = userTaskData[key]
      }
    }
    data['bpmn:definitions']['bpmn:process'][nodeType] = temp
  } else if (userTaskData?.constructor === Array) {
    const arr: Array<Object> = []
    userTaskData.forEach((item) => {
      const temp = {}
      for (const key in item) {
        if (key !== 'bpmn:outgoing' && key !== 'multiInstanceLoopCharacteristics') {
          temp[key] = item[key]
        }
      }
      for (const key in item) {
        if (key === 'bpmn:outgoing') {
          temp[key] = item[key]
        }
      }
      for (const key in item) {
        if (key === 'multiInstanceLoopCharacteristics') {
          temp[key] = item[key]
        }
      }
      arr.push(temp)
    })
    data['bpmn:definitions']['bpmn:process'][nodeType] = arr
  }
}

const downloadXml = () => {
  const data = props.lf.getGraphData() as string
  const drawData = props.lf.getGraphRawData()
  let userTaskData = data['bpmn:definitions']['bpmn:process'].userTask
  userTaskData = userTaskData?.constructor === Array ? userTaskData : [userTaskData]
  if (data['bpmn:definitions']['bpmn:process'].exclusiveGateway) {
    const exclusiveGatewayData = data['bpmn:definitions']['bpmn:process'].exclusiveGateway
    sortInOut(data, exclusiveGatewayData, 'exclusiveGateway')
    userTaskData.push(exclusiveGatewayData)
  }
  // 先初始化第0个数据进去
  const newUserTaskData = [userTaskData[0]]
  // // 循环次数
  const count = userTaskData.length - 1
  // 除发起节点还有用户节点的情况，要重新调整下顺序
  if (count > 0) {
    // 是否需要重新赋值标识
    let flag = true
    for (let index = 0; index < count; index++) {
      // 取得outgoing参数
      const outgoing = newUserTaskData[index]?.['bpmn:outgoing']
      if (outgoing === undefined) {
        flag = false
        break
      }
      // 这里给用户节点重新排序
      for (const item in userTaskData) {
        const incoming = userTaskData[item]?.['bpmn:incoming']
        if (incoming === undefined) {
          flag = false
          break
        }
        // 判断incoming和outgoing是否有交集，有就表示他们之间有连线
        // 同时判断newUserTaskData是否首次添加，已添加的就不用再加了
        if (
          intersection(isArray(outgoing) ? outgoing : [outgoing], isArray(incoming) ? incoming : [incoming]).length &&
          intersectionBy(newUserTaskData, [userTaskData[item]], '-id').length === 0
        ) {
          newUserTaskData.push(userTaskData[item])
          // break
        }
      }
    }
    console.log(flag)
    // 重新复制，当节点信息正确的时候才重新赋值
    if (data['bpmn:definitions']['bpmn:process'].exclusiveGateway) {
      userTaskData = newUserTaskData.filter((item) => !item['-name'].includes('条件判断'))
    }
  }

  sortInOut(data, userTaskData, 'userTask')

  // console.log(data)

  // 调整连接线中属性顺序，conditionValue需要在xsi:type前面
  data['bpmn:definitions']['bpmn:process']['bpmn:sequenceFlow'].forEach((item) => {
    const temp: any = {}
    if (item.conditionExpression) {
      temp.liu = {}
      temp['-conditionValue'] = item.conditionExpression['-conditionValue']
      temp['-xsi:type'] = item.conditionExpression['-xsi:type']
      item.conditionExpression = temp
    }
  })
  // console.log('drawData', JSON.stringify(drawData))
  const xmlData = lfJson2Xml(data)
  // download('logic-flow.xml', xmlData)
  return { xmlData, drawData: JSON.stringify(drawData) }
}
const downloadImage = () => {
  props.lf.getSnapshot()
}
const uploadXml = (ev: Event) => {
  const file = (ev.target as FileEventTarget).files[0]
  const reader = new FileReader()
  reader.onload = (event: ProgressEvent<FileReader>) => {
    if (event.target) {
      const data = event.target.result as string
      /* 这里JSON无法解析，只有XML可以载入？？
          if (isJSON(data)) {
            data = JSON.parse(data);
          }
          */
      props.lf.render(data)
    }
  }
  reader.readAsText(file) // you could also read images and other binaries
}
const getGraphRawData = () => {
  const data = JSON.stringify(props.lf.getGraphRawData())
  download('logic-flow.txt', data)
}

defineExpose({
  downloadXml,
  downloadImage,
  uploadXml,
  getGraphRawData
})
</script>
<style>
.data-panel {
  position: absolute;
  bottom: 10px;
  left: 10px;
  /* height: 20px; */
  width: auto;
  padding: 10px;
  background-color: white;
  box-shadow: 0 0 10px 1px rgb(228, 224, 219);
  border-radius: 6px;
  text-align: center;
  z-index: 101;
}
.data-item {
  margin: 0px 5px;
  display: inline-block;
  position: relative;
}
.data-item-icon {
  width: 20px;
  height: 20px;
  background-size: cover;
}
.data-label {
  font-size: 12px;
  margin-top: 5px;
  user-select: none;
}

.data-upload {
  opacity: 0;
  position: absolute;
  width: 20px;
  height: 20px;
  left: 0;
  right: 0;
}

.bpmn-xml {
  background: url()
    center center no-repeat;
  cursor: grab;
}

.bpmn-img {
  background: url()
    center center no-repeat;
  cursor: grab;
}

.bpmn-upload {
  background: url()
    center center no-repeat;
  cursor: grab;
}

.bpmn-look {
  background: url()
    center center no-repeat;
  cursor: grab;
}
</style>
